/**
 * enum_generator宏
 *
 * 这是一个宏定义，用于生成枚举类型及其从i32、&str转换的实现。
 * 每个宏带两个参数,分别是枚举对应的显示内容和数据库存储的值。
 * 将自动实现 Debug..以及与i32,&str的转换。
 * 注意:每一个枚举会自动多生成一个UnknownValue枚举成员，用于表示未知的枚举值.其值为i32::MIN
 *
 * 使用示例：
 * ```ignore
 * enum_generator! {
 *   Debug, Clone; MyEnum { Value1("value1", 1), Value2("value2", 2)
 * }
 * ```
 * 上述例子会生成如下代码：
 * ```ignore
 * #[derive(Debug, Clone)]
 * pub enum MyEnum {
 *   Value1,
 *   Value2,
 *   UnknownValue
 * }
 *
 * impl From<i32> for MyEnum {...}
 * impl From<MyEnum> for i32 {...}
 * impl From<&str> for MyEnum {...}
 * impl From<MyEnum> for &str {...}
 * ```
 */
#[macro_export]
macro_rules! enum_generator {
  () => {};
  // ($name:ident {$($(#[$m:meta])* $tt:ident($v:literal,$n:literal) $(,)? )*}) => {
	// 	$crate::enum_generator!{ $name {$($(#[$m])* $tt($v,$n),)*}}
	// };
  ($(#[$de:meta])* $name:ident{$($(#[$m:meta])* $tt:ident($v:literal,$n:literal),)*}) => {
		#[derive(Debug,PartialEq,Clone, Eq,PartialOrd,Ord,)]
		$(#[$de])*
		pub enum $name {
			$($(#[$m])*
				$tt,
			)*
			UnknownValue
		}

		impl $name {
			pub fn as_str<'a>(&'a self) -> &'a str {
				match self {
					$(
						$name::$tt => $v,
					)*
					$name::UnknownValue => "UnknownValue",
				}
			}
			pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
				match self {
					$($name::$tt => $v.as_bytes(),)*
					$name::UnknownValue => b"UnknownValue",
				}
			}
		}

		impl From<i32> for $name {
			fn from(value: i32) -> Self {
				match value {
					$($n => $name::$tt,)*
					_ => $name::UnknownValue,
				}
			}
		}

		impl From<$name> for i32 {
			fn from(value: $name) -> Self {
				match value {
					$($name::$tt => $n,)*
					$name::UnknownValue => i32::MIN
				}
			}
		}

		impl From<&str> for $name {
			fn from(value: &str) -> Self {
				match value {
					$($v => $name::$tt,)*
					_ => $name::UnknownValue,
				}
			}
		}

		impl From<$name> for &str {
			fn from(value: $name) -> &'static str {
				match value {
					$($name::$tt => $v,)*
					$name::UnknownValue => "未知"
				}
			}
		}

		impl core::fmt::Display for $name {
			fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(
					match self {
						$($name::$tt => $v,)*
						$name::UnknownValue => "UnknownValue",
					},
				)
			}
		}

		impl Default for $name {
			#[inline]
			fn default() -> $name {
				$name::UnknownValue
			}
		}
  };
}
